package org.light.generator;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.light.core.GinController;
import org.light.core.Writeable;
import org.light.domain.Controller;
import org.light.domain.Domain;
import org.light.domain.Method;
import org.light.domain.Statement;
import org.light.exception.ValidateException;
import org.light.utils.DomainUtil;
import org.light.utils.StringUtil;
import org.light.utils.WriteableUtil;

public class RouterGenerator{
	protected Set<GinController> controllers = new TreeSet<>();
	protected Domain sampleDomain;
	protected String fileName = "router.go";
	
	public RouterGenerator(){
		this.fileName = "router.go";
	}
	
	public String generateRouterString() throws ValidateException{
		List<Writeable> sList = new ArrayList<Writeable>();
		sList.add(new Statement(1000L,0,"package router"));
		sList.add(new Statement(2000L,0,""));
		sList.add(new Statement(3000L,0,"import ("));
		sList.add(new Statement(4000L,1,"\""+DomainUtil.packagetokenToGoPackageFolder(this.sampleDomain.getProjectName(),this.sampleDomain.getPackageToken()+"."+this.sampleDomain.getControllerSuffix()+"\"")));
		sList.add(new Statement(6000L,0,""));
		sList.add(new Statement(7000L,1,"\"github.com/gin-gonic/gin\""));
		sList.add(new Statement(8000L,0,")"));
		sList.add(new Statement(9000L,0,""));
		sList.add(new Statement(11000L,0,"func InitRouter(g *gin.Engine) {"));
		sList.add(new Statement(25000L,1,"// The health check handlers"));
		int index = 0;
		long serial =  26000L;
		for (Controller c:this.controllers) {
			sList.add(new Statement(serial,1,"router"+index+" := g.Group(\"/"+c.getDomain().getLowerFirstDomainName()+c.getDomain().getControllerNamingSuffix()+"\")"));
			sList.add(new Statement(serial+1000L,1,"{"));
			serial += 2000L;
			for (Method m:c.getMethods()) {
				if (!m.getStandardName().startsWith("Export")&&!m.getStandardName().startsWith("Filter")) {
					sList.add(new Statement(serial,2,"router"+index+".POST(\"/"+StringUtil.lowerFirst(m.getStandardName())+"\", "+c.getDomain().getControllerSuffix()+"."+m.getStandardName()+")"));
				}else {
					sList.add(new Statement(serial,2,"router"+index+".GET(\"/"+StringUtil.lowerFirst(m.getStandardName())+"\", "+c.getDomain().getControllerSuffix()+"."+m.getStandardName()+")"));
				}
				serial += 1000L;
			}
			sList.add(new Statement(serial,1,"}"));
			sList.add(new Statement(serial+1000L,0,""));
			serial += 2000L;
			index++;
		}
		sList.add(new Statement(serial,0,"}"));
		return WriteableUtil.merge(sList).getContent();
	}

	public Set<GinController> getControllers() {
		return controllers;
	}

	public void setControllers(Set<GinController> controllers) {
		this.controllers = controllers;
	}

	public RouterGenerator(Set<GinController> controllers) {
		super();
		if (controllers!=null&& controllers.size()>0) {
			this.controllers = controllers;
			for (Controller c:controllers) {
				this.sampleDomain = c.getDomain();
				break;
			}
		}		
	}

	public Domain getSampleDomain() {
		return sampleDomain;
	}

	public void setSampleDomain(Domain sampleDomain) {
		this.sampleDomain = sampleDomain;
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
}
